package com.copractice.bl.tags;

import java.util.ArrayList;
import java.util.List;

import org.hibernate.Transaction;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.copractice.data.dao.hibernate.util.DBUtils;
import com.copractice.data.dao.knowledge.UsersKnowledgeDAO;
import com.copractice.data.dao.question.QuestionDAO;
import com.copractice.data.dao.tag.TagDAO;
import com.copractice.data.entity.knowledge.UsersKnowledge;
import com.copractice.data.entity.tag.Tag;
import com.google.inject.Inject;

/**
 * Contains business logic methods of working with tags.
 * 
 * @author Dmitry Churbanov (dmitry.churbanov@gmail.com)
 * @version 1.0 01/03/2010
 */
public class TagsBL {
    
    private static final Logger LOG = LoggerFactory.getLogger(TagsBL.class);
    
    private TagDAO tagDAO;
    private QuestionDAO questionDAO;
    private UsersKnowledgeDAO userKnowledgeDAO;
    
    public TagDAO getTagDAO() {
        return tagDAO;
    }

    @Inject
    public void setTagDAO(TagDAO tagDAO) {
        this.tagDAO = tagDAO;
    }

    public QuestionDAO getQuestionDAO() {
        return questionDAO;
    }

    @Inject
    public void setQuestionDAO(QuestionDAO questionDAO) {
        this.questionDAO = questionDAO;
    }

    public UsersKnowledgeDAO getUserKnowledgeDAO() {
        return userKnowledgeDAO;
    }

    @Inject
    public void setUserKnowledgeDAO(UsersKnowledgeDAO userKnowledgeDAO) {
        this.userKnowledgeDAO = userKnowledgeDAO;
    }

    /**
     * Returns the list of all tags. 
     * 
     * @return the<code>List</code> of all tags.
     */
    public List<Tag> getAllTags() {
        Transaction tx = null;
        List<Tag> listOfTags = new ArrayList<Tag>();
        try {
          tx = DBUtils.beginTransaction();
          listOfTags = tagDAO.findAll();

          if(LOG.isDebugEnabled()) {
              LOG.debug("Areas Info: {}", listOfTags);
          }
          tx.commit();
        } catch(RuntimeException ex) {
          if (LOG.isDebugEnabled()) {
            LOG.debug("Rollback the transaction");
          }
          tx.rollback();
        }          
        
        return listOfTags;
    }
    
    /**
     * Finds <code>Tag</code> by it's id value.
     *  
     * @param id id of a tag to find.
     * @return instance of a <code>Tag</code> value, or null if there is no Tag with such id value.
     */
    public Tag getTag(Long id) {

        if(LOG.isDebugEnabled()) {
            LOG.debug("Tag id: {}", id);
        }        
        return tagDAO.getById(id);
    }    
    
    /**
     * Returns the list of <code>AreaInfo</code> objects which contain info
     * about each area (tag) for the user with <code>userId</code> id.
     * 
     * @param userId the id of a user
     * @return the list of <code>AreaInfo</code> objects
     */
    
    public List<TagsInfo> getAreaInfo(Long userId) {
        Transaction tx = null;
        List<TagsInfo> tagsInfoList = new ArrayList<TagsInfo>();
        try {
            tx = DBUtils.beginTransaction();
            List<Tag> listOfTags = tagDAO.findAll();
            
            if (LOG.isDebugEnabled()) {
                LOG.debug("Found list of tags = {}", listOfTags);
            }
            
            for(Tag tag : listOfTags) {
                TagsInfo areaInfo = new TagsInfo(tag.getId(), tag.getName(), questionDAO.getQuestions(tag.getId()).size());
                
                //TODO
                //setTeachingLearningScores(areaInfo, userId, tag.getId());
                tagsInfoList.add(areaInfo);
            }
            tx.commit();
        } catch(RuntimeException ex) {
            if (LOG.isDebugEnabled()) {
                LOG.debug("Rollback the transaction: userId = {}", userId);
            }
            tx.rollback();
            if (LOG.isDebugEnabled()) {
                throw new RuntimeException(ex);
            }
        }
        
        return tagsInfoList;
    }
    
    /*
    private void setTeachingLearningScores(TagsInfo tagsInfo, Long userId, Long tagId) {
        UsersKnowledge usersKnowledge = userKnowledgeDAO.fetchUserKnowledgeByUserIdAndTagId(userId, tagId);
        if (usersKnowledge != null) {
            UserKnowledgeBL userKnowledgeBL = new UserKnowledgeBL();
            tagsInfo.setScore(userKnowledgeBL.calculateLearningScore(usersKnowledge), 
                              usersKnowledge.getTeachingScore());
        } else {
            tagsInfo.setScore(0L, 0L);
        }
    }
    */
    
    
}
